Skip to content

Navigation, sheets, alert, and tabs - #23

Merged
colemancda merged 7 commits into
masterfrom
feature/navigation-r6
Jul 23, 2026
Merged

Navigation, sheets, alert, and tabs#23
colemancda merged 7 commits into
masterfrom
feature/navigation-r6

Conversation

@colemancda

Copy link
Copy Markdown
Member

Sixth step of the Compose-backed architecture (#18#22). Restores real navigation and adds the presentation surface — including alert, which the classic-view renderer had no path to at all.

Navigation

Swift owns the stack. NavigationStack holds a NavigationModel persisted by identity path; links push, @Environment(\.dismiss) pops, navigationDestination(for:) resolves value pushes, navigationTitle records per-screen titles. The stack emits every screen (root + pushed) as children, so the interpreter can animate between them with AnimatedContent and render the outgoing screen from cache during a pop. Scaffold + TopAppBar gives the title and a back arrow; system back flows through the same pop callback.

Presentation

  • Sheet: .sheet(isPresented:) rides as a hidden child shown while the flag is true; the interpreter presents it as a ModalBottomSheet. Drag-to-dismiss and the dismiss action write the flag back, so Swift stays authoritative. presentationDetents supported.
  • Alert: .alert(_:isPresented:message:buttons:) → Material 3 AlertDialog. New API — no Alert type existed under the old architecture.
  • The normal child loop skips these hidden presentation nodes so they never render inline.

Tabs

TabView(selection:) with .tabItem and .tag; the interpreter renders a NavigationBar and shows the tagged tab. Selection is a @State binding, so both a tab tap and programmatic selection work.

Core additions

  • @Environment gains the keyPath form (\.dismiss) alongside object injection, both through the same reflection seam.
  • StateStorage.persistentObject(at:) holds container reference state (the nav stack) that must survive re-evaluation without living in a view's @State.
  • The evaluator now installs state and injects environment for primitives (so containers hold state), handles _ResolutionEffectView wrappers (title/destination registration), and threads a per-screen title/detent sink.

Verification

  • swift test: 24 tests — classic push, value push through navigationDestination, dismiss-pops, sheet presentation, tab selection.
  • Emulator, full journeys:
    • Gallery renders as a NavigationStack ("Gallery" app bar, 10 links); tapping a row pushes with a back arrow; back pops.
    • Value-based navigation: Navigation → Push value 1 → "Value 1" screen resolved via navigationDestination, with its own title, and a further "Push value 2" link — the deepest path (a pushed screen registering a destination and pushing onto the same Swift-owned stack).
    • Sheet presents as a bottom modal and dismisses via @Environment(\.dismiss).
    • Alert shows title/message/OK/Cancel.
    • Tabs: bottom bar One/Two/Three; the "Select third tab" button drives @State and switches to Third tab.

…ge, resolution effects

@Environment gains keyPath form (\.dismiss) alongside object injection;
StateStorage persists container reference objects by identity path; the
evaluator installs state and injects environment for primitives, handles
resolution-effect wrappers, and threads a per-screen title/detent sink.
Swift owns the stack; links push, dismiss pops, navigationDestination resolves
value pushes, navigationTitle records per-screen titles. The stack emits every
screen so Compose can animate and cache during a pop.
Modal content rides as a hidden child shown while its bound flag is true;
drag-to-dismiss and dialog buttons write the flag back so Swift stays
authoritative. Alert is new API the classic renderer never had.
NavStack renders a Scaffold with a back-arrow app bar and animates between
cached screens; sheets present as a ModalBottomSheet, alerts as an
AlertDialog, both skipped by the normal child loop; TabView renders a
NavigationBar and shows the tagged tab.
@colemancda
colemancda merged commit 33aa263 into master Jul 23, 2026
6 checks passed
@colemancda
colemancda deleted the feature/navigation-r6 branch July 23, 2026 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant